package com.transaction.manage.controller;

import com.transaction.common.base.BaseController;
import com.transaction.common.base.PageInfo;
import com.transaction.common.util.DateUtil;
import com.transaction.common.util.JsonUtil;
import com.transaction.common.util.ParamsUtil;
import com.transaction.manage.model.dto.*;
import com.transaction.manage.model.vo.HandleVo;
import com.transaction.manage.service.BaseParamsService;
import com.transaction.manage.service.BusinessHandleService;
import com.transaction.manage.service.dayEnd.HandleDataCheck;
import com.transaction.manage.util.MultiThreadedUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/businessHandle")
@ApiIgnore
public class BusinessHandleController extends BaseController {


    private static Logger LOGGER = LoggerFactory.getLogger(BusinessHandleController.class);

    @Autowired
    private BusinessHandleService businessHandleService;

    @Autowired
    private BaseParamsService baseParamsService;

    @Autowired
    private HandleDataCheck handleDataCheck;

    /**
     * 查询日终处理页面信息
     * @param request
     * @return
     */
    @GetMapping("/selectDayEndHandleList")
    public Object selectDayEndHandleList(HttpServletRequest request){
        FlowLog flowLog = ParamsUtil.getBeanParam(new FlowLog(DateUtil.formatDate(new Date(),DateUtil.FORMAT_STR_TIME10)),request);
        return retResultVo(businessHandleService.selectDayEndHandleList(flowLog));
    }

    /**
     * 根据流程编码查询流程信息
     * @return
     */
    @GetMapping("/selectFlowInfoByFlowCode")
    public Object selectFlowInfoByFlowCode(String flowCode){
        List<FlowInfo> list = businessHandleService.selectFlowStepCodeNameByFlowCode(flowCode);
        return retResultVo(list);
    }

    /**
     * 日终数据处理
     * @param dayEndHandleVo
     * @return
     */
    @PostMapping("/dayEndHandle")
    public Object dayEndHandle(@RequestBody DayEndHandleVo dayEndHandleVo ){
        String flowCode = dayEndHandleVo.getFlowCode();
        String handleDate = dayEndHandleVo.getHandleDate();
        List<String> channelCodes = dayEndHandleVo.getChannelCodes();
        if(StringUtils.isEmpty(flowCode) || StringUtils.isEmpty(handleDate)){
            throw new RuntimeException("处理流程/处理日期不能为空。");
        }

        List<FlowInfo> flowInfoList = businessHandleService.selectFlowInfoList(flowCode,null);

        if(CollectionUtils.isEmpty(flowInfoList)){
            throw new RuntimeException("流程信息配置为空,请配置。");
        }

        if(CollectionUtils.isEmpty(channelCodes)){
            //如果没有勾选,全量处理
            channelCodes = baseParamsService.selectChannelInfoList(null,new PageInfo())
                    .stream()
                    .map(ChannelInfo::getChannelCode)
            .collect(Collectors.toList());
        }

        LOGGER.info("日终数据处理渠道数据为:【【{}】】,日期为:【【{}】】,处理流程为:【【{}】】",channelCodes.toString(),handleDate,flowCode);
        List<HandleVo> list = MultiThreadedUtil.multiHandleDate(flowInfoList,channelCodes,handleDate,flowCode);
        if(CollectionUtils.isEmpty(list)){
            return retResultVo("处理完成。");
        }else{
            StringBuilder  msg= new StringBuilder();
            list.forEach(v->{
                msg.append(v.getRetMsg());
            });
            return retResultVo(msg.toString());
        }
    }

    /**
     * 重做错误节点
     * @param dayEndHandleVo
     * @return
     */
    @PostMapping("/reloadErrorStep")
    public Object reloadErrorStep(@RequestBody DayEndHandleVo dayEndHandleVo ){
        /**
         * 1、验证传入的步骤是否是当前渠道的最新的错误步骤
         * 2、调用批量处理流程
         */
        String flowCode = dayEndHandleVo.getFlowCode();
        String handleDate = dayEndHandleVo.getHandleDate();
        String channelCode = dayEndHandleVo.getChannelCode();
        Integer stepCode = dayEndHandleVo.getStepCode();

        if(StringUtils.isEmpty(flowCode) || StringUtils.isEmpty(handleDate)
                || stepCode == null || StringUtils.isEmpty(channelCode)){
            throw new RuntimeException("处理流程/处理日期/渠道编码/步骤节点不能为空。");
        }

        boolean flag = handleDataCheck.checkStepIsNewestErrorStep(flowCode,channelCode,handleDate,stepCode);
        if(!flag){
            throw new RuntimeException("传入的流程节点不是该渠道最新的错误节点。");
        }

        //重做该步,把该节点错误的数据更新成成功,再次校验
        businessHandleService.recoverFailedData(channelCode,handleDate,stepCode);

        LOGGER.info("流程：【{}】，渠道：【{}】，处理日期：【{}】，步骤节点：【{}】，重做该错误步骤操作。",flowCode,channelCode,handleDate,stepCode);
        return dayEndStepHandle(flowCode,handleDate,channelCode,stepCode);
    }

    /**
     * 跳过错误节点
     * @param dayEndHandleVo
     * @return
     */
    @PostMapping("/skipErrorStep")
    public Object skipErrorStep(@RequestBody DayEndHandleVo dayEndHandleVo ){
        /**
         * 1、验证传入的步骤是否是当前渠道的最新的错误步骤
         * 2、调用批量处理流程
         */
        String flowCode = dayEndHandleVo.getFlowCode();
        String handleDate = dayEndHandleVo.getHandleDate();
        String channelCode = dayEndHandleVo.getChannelCode();
        Integer stepCode = dayEndHandleVo.getStepCode();
        if(StringUtils.isEmpty(flowCode) || StringUtils.isEmpty(handleDate)
                || stepCode == null || StringUtils.isEmpty(channelCode)){
            throw new RuntimeException("处理流程/处理日期/渠道编码/步骤节点不能为空。");
        }

        boolean flag = handleDataCheck.checkStepIsNewestErrorStep(flowCode,channelCode,handleDate,stepCode);
        if(!flag){
            throw new RuntimeException("传入的流程节点不是该渠道最新的错误节点。");
        }
        LOGGER.info("流程：【{}】，渠道：【{}】，处理日期：【{}】，步骤节点：【{}】，跳过该错误步骤操作。",flowCode,channelCode,handleDate,stepCode);
        return dayEndStepHandle(flowCode,handleDate,channelCode,stepCode + 1);
    }


    /**
     * 日终处理流程步骤节点操作，强制通过，或者重做该步
     * @return
     */
    public Object dayEndStepHandle(String flowCode,String handleDate,String channelCode,Integer stepCode){
        List<FlowInfo> flowInfoList = businessHandleService.selectFlowInfoList(flowCode,stepCode);
        List<String> channelCodes = new ArrayList<String>(){{add(channelCode);}};
        List<HandleVo> list = MultiThreadedUtil.multiHandleDate(flowInfoList,channelCodes,handleDate,flowCode);
        if(CollectionUtils.isEmpty(list)){
            return retResultVo("处理完成。");
        }else{
            return retResultVo(list.get(1).getRetMsg());
        }
    }


    /**
     * 根据错误编码查询错误详情
     * @param logCode 日志编码
     * @return
     */
    @GetMapping("/selectLogDetailByLogCode")
    public Object selectLogDetailByLogCode(String logCode){
        LogDetail logDetail = businessHandleService.selectLogDetailByLogCode(logCode);
        return retResultVo(logDetail == null ? "没有错误详情。" : logDetail.getMsgDetail());
    }

}
